# 导入Pandas库并将其命名为pd
import pandas as pd
# 使用Pandas的read_excel函数从employee_leaves.xlsx文件中读取数据,并将数据存储在名为df的数据框中
df = pd.read_excel('employee_leaves.xlsx')
df
| 工资 | 满意度 | 考核得分 | 工程数量 | 月工时 | 工龄 | 离职 | |
|---|---|---|---|---|---|---|---|
| 0 | 低 | 3.8 | 0.53 | 2 | 157 | 3 | 1 |
| 1 | 中 | 8.0 | 0.86 | 5 | 262 | 6 | 1 |
| 2 | 中 | 1.1 | 0.88 | 7 | 272 | 4 | 1 |
| 3 | 低 | 7.2 | 0.87 | 5 | 223 | 5 | 1 |
| 4 | 低 | 3.7 | 0.52 | 2 | 159 | 3 | 1 |
| ... | ... | ... | ... | ... | ... | ... | ... |
| 14995 | 高 | 9.0 | 0.55 | 3 | 259 | 10 | 0 |
| 14996 | 高 | 7.4 | 0.95 | 5 | 266 | 10 | 0 |
| 14997 | 高 | 8.5 | 0.54 | 3 | 185 | 10 | 0 |
| 14998 | 高 | 3.3 | 0.65 | 3 | 172 | 10 | 0 |
| 14999 | 低 | 5.0 | 0.73 | 4 | 180 | 3 | 0 |
15000 rows × 7 columns
# 将数据框中名为'工资'的列中的值进行替换。具体来说,将'低'替换为0,'中'替换为1,'高'替换为2。
df = df.replace({'工资': {'低': 0, '中': 1, '高': 2}})
df
| 工资 | 满意度 | 考核得分 | 工程数量 | 月工时 | 工龄 | 离职 | |
|---|---|---|---|---|---|---|---|
| 0 | 0 | 3.8 | 0.53 | 2 | 157 | 3 | 1 |
| 1 | 1 | 8.0 | 0.86 | 5 | 262 | 6 | 1 |
| 2 | 1 | 1.1 | 0.88 | 7 | 272 | 4 | 1 |
| 3 | 0 | 7.2 | 0.87 | 5 | 223 | 5 | 1 |
| 4 | 0 | 3.7 | 0.52 | 2 | 159 | 3 | 1 |
| ... | ... | ... | ... | ... | ... | ... | ... |
| 14995 | 2 | 9.0 | 0.55 | 3 | 259 | 10 | 0 |
| 14996 | 2 | 7.4 | 0.95 | 5 | 266 | 10 | 0 |
| 14997 | 2 | 8.5 | 0.54 | 3 | 185 | 10 | 0 |
| 14998 | 2 | 3.3 | 0.65 | 3 | 172 | 10 | 0 |
| 14999 | 0 | 5.0 | 0.73 | 4 | 180 | 3 | 0 |
15000 rows × 7 columns
# 从employee_leaves.xlsx文件中读取数据,并将数据存储在名为df的数据框中
df = pd.read_excel('employee_leaves.xlsx')
# 使用Pandas的get_dummies函数对数据框df中的'工资'列进行独热编码处理,创建新的列来表示不同的工资水平
df = pd.get_dummies(df, columns=['工资'])
df
| 满意度 | 考核得分 | 工程数量 | 月工时 | 工龄 | 离职 | 工资_中 | 工资_低 | 工资_高 | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 3.8 | 0.53 | 2 | 157 | 3 | 1 | 0 | 1 | 0 |
| 1 | 8.0 | 0.86 | 5 | 262 | 6 | 1 | 1 | 0 | 0 |
| 2 | 1.1 | 0.88 | 7 | 272 | 4 | 1 | 1 | 0 | 0 |
| 3 | 7.2 | 0.87 | 5 | 223 | 5 | 1 | 0 | 1 | 0 |
| 4 | 3.7 | 0.52 | 2 | 159 | 3 | 1 | 0 | 1 | 0 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 14995 | 9.0 | 0.55 | 3 | 259 | 10 | 0 | 0 | 0 | 1 |
| 14996 | 7.4 | 0.95 | 5 | 266 | 10 | 0 | 0 | 0 | 1 |
| 14997 | 8.5 | 0.54 | 3 | 185 | 10 | 0 | 0 | 0 | 1 |
| 14998 | 3.3 | 0.65 | 3 | 172 | 10 | 0 | 0 | 0 | 1 |
| 14999 | 5.0 | 0.73 | 4 | 180 | 3 | 0 | 0 | 1 | 0 |
15000 rows × 9 columns
## 导入LabelEncoder类从sklearn.preprocessing模块
from sklearn.preprocessing import LabelEncoder
# 从employee_leaves.xlsx文件中读取数据,并将数据存储在名为df的数据框中
df = pd.read_excel('employee_leaves.xlsx')
# 创建一个LabelEncoder对象
le = LabelEncoder()
# 使用LabelEncoder对象对'工资'列进行标签编码,将分类变量转换为数值编码
label = le.fit_transform(df['工资'])
label
array([1, 0, 0, ..., 2, 2, 1])
# 将标签编码后的数值赋值给'工资'列
df['工资'] = label
df
| 工资 | 满意度 | 考核得分 | 工程数量 | 月工时 | 工龄 | 离职 | |
|---|---|---|---|---|---|---|---|
| 0 | 1 | 3.8 | 0.53 | 2 | 157 | 3 | 1 |
| 1 | 0 | 8.0 | 0.86 | 5 | 262 | 6 | 1 |
| 2 | 0 | 1.1 | 0.88 | 7 | 272 | 4 | 1 |
| 3 | 1 | 7.2 | 0.87 | 5 | 223 | 5 | 1 |
| 4 | 1 | 3.7 | 0.52 | 2 | 159 | 3 | 1 |
| ... | ... | ... | ... | ... | ... | ... | ... |
| 14995 | 2 | 9.0 | 0.55 | 3 | 259 | 10 | 0 |
| 14996 | 2 | 7.4 | 0.95 | 5 | 266 | 10 | 0 |
| 14997 | 2 | 8.5 | 0.54 | 3 | 185 | 10 | 0 |
| 14998 | 2 | 3.3 | 0.65 | 3 | 172 | 10 | 0 |
| 14999 | 1 | 5.0 | 0.73 | 4 | 180 | 3 | 0 |
15000 rows × 7 columns
# 数据集中的“离职”列是目标变量,将其余列作为特征
X = df.drop('离职', axis=1) # 特征
X
| 工资 | 满意度 | 考核得分 | 工程数量 | 月工时 | 工龄 | |
|---|---|---|---|---|---|---|
| 0 | 1 | 3.8 | 0.53 | 2 | 157 | 3 |
| 1 | 0 | 8.0 | 0.86 | 5 | 262 | 6 |
| 2 | 0 | 1.1 | 0.88 | 7 | 272 | 4 |
| 3 | 1 | 7.2 | 0.87 | 5 | 223 | 5 |
| 4 | 1 | 3.7 | 0.52 | 2 | 159 | 3 |
| ... | ... | ... | ... | ... | ... | ... |
| 14995 | 2 | 9.0 | 0.55 | 3 | 259 | 10 |
| 14996 | 2 | 7.4 | 0.95 | 5 | 266 | 10 |
| 14997 | 2 | 8.5 | 0.54 | 3 | 185 | 10 |
| 14998 | 2 | 3.3 | 0.65 | 3 | 172 | 10 |
| 14999 | 1 | 5.0 | 0.73 | 4 | 180 | 3 |
15000 rows × 6 columns
y = df['离职'] # 目标变量
y
0 1
1 1
2 1
3 1
4 1
..
14995 0
14996 0
14997 0
14998 0
14999 0
Name: 离职, Length: 15000, dtype: int64
# 导入train_test_split函数从sklearn.model_selection模块
from sklearn.model_selection import train_test_split
# 使用train_test_split函数将特征数据集X和目标数据集y划分为训练集和测试集,测试集占比为20%,设置随机种子为123
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=123)
print(X_train.shape,X_test.shape,y_train.shape,y_test.shape) # 显示划分的形状大
X_train
(12000, 6) (3000, 6) (12000,) (3000,)
| 工资 | 满意度 | 考核得分 | 工程数量 | 月工时 | 工龄 | |
|---|---|---|---|---|---|---|
| 3553 | 1 | 7.3 | 0.93 | 5 | 162 | 4 |
| 2112 | 1 | 4.3 | 0.52 | 2 | 160 | 3 |
| 1794 | 1 | 3.8 | 0.51 | 2 | 159 | 3 |
| 13886 | 1 | 6.3 | 0.71 | 4 | 244 | 2 |
| 11251 | 0 | 8.8 | 0.71 | 5 | 219 | 2 |
| ... | ... | ... | ... | ... | ... | ... |
| 5218 | 0 | 6.3 | 0.80 | 4 | 256 | 4 |
| 12252 | 1 | 9.2 | 0.76 | 5 | 132 | 3 |
| 1346 | 1 | 7.3 | 0.95 | 4 | 223 | 6 |
| 11646 | 0 | 8.5 | 0.76 | 3 | 197 | 5 |
| 3582 | 0 | 5.6 | 0.58 | 4 | 258 | 3 |
12000 rows × 6 columns
# 导入DecisionTreeClassifier类从sklearn.tree模块
from sklearn.tree import DecisionTreeClassifier
# 创建一个DecisionTreeClassifier对象,设置最大深度为3,随机种子为123
dtc = DecisionTreeClassifier(max_depth=3, random_state=123)
# 使用训练集数据对决策树分类器进行训练
dtc.fit(X_train, y_train)
# 使用训练好的模型对测试集数据进行预测
y_pred = dtc.predict(X_test)
# 输出测试集前100个样本的分类结果
y_pred[:100]
array([0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1,
0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0], dtype=int64)
# 获取样本在决策树中的叶子节点索引
y_pre = dtc.apply(X_test)
y_pre[:100]
array([10, 10, 14, 10, 7, 7, 3, 10, 7, 7, 10, 10, 10, 10, 7, 3, 10,
14, 10, 7, 10, 10, 10, 10, 7, 13, 10, 6, 3, 10, 14, 10, 3, 10,
10, 14, 10, 3, 10, 10, 10, 10, 10, 14, 10, 7, 10, 10, 10, 10, 10,
3, 10, 10, 3, 13, 10, 3, 10, 13, 10, 14, 10, 14, 6, 7, 10, 10,
10, 13, 10, 10, 7, 10, 10, 7, 3, 10, 10, 10, 10, 10, 10, 7, 10,
10, 14, 10, 10, 6, 7, 13, 10, 10, 6, 6, 6, 13, 10, 10],
dtype=int64)
# 创建一个DataFrame,包含预测值和实际值
comparison_df = pd.DataFrame({'实际值': y_test, '预测值': y_pred})
# 显示样本的比较结果
comparison_df
| 实际值 | 预测值 | |
|---|---|---|
| 6958 | 0 | 0 |
| 7534 | 0 | 0 |
| 2975 | 1 | 1 |
| 3903 | 0 | 0 |
| 8437 | 0 | 0 |
| ... | ... | ... |
| 1229 | 1 | 1 |
| 10594 | 0 | 0 |
| 13211 | 0 | 0 |
| 3147 | 1 | 1 |
| 6623 | 0 | 0 |
3000 rows × 2 columns
# 评估决策树模型
from sklearn.metrics import accuracy_score, roc_curve, roc_auc_score
import matplotlib.pyplot as plt
# 使用模型的score函数检查预测准确度
accuracy = dtc.score(X_test, y_test)
print("预测准确度: {:.6f}".format(accuracy))
预测准确度: 0.957333
# 获取每个类别的预测概率
y_pred_proba = dtc.predict_proba(X_test)
class_names = ["不离职概率", "离职概率"]
# 显示每个样本的预测概率
print("{:<3} {:<7} {:<5}".format("",class_names[0], class_names[1]))
for i in range(20): # 显示前20行数据,若显示全部数据将20替换成len(y_pred_proba)
print("{:<5} {:.6f} {:.6f}".format(i, y_pred_proba[i][0], y_pred_proba[i][1]))
不离职概率 离职概率 0 0.985261 0.014739 1 0.985261 0.014739 2 0.286006 0.713994 3 0.985261 0.014739 4 0.922832 0.077168 5 0.922832 0.077168 6 0.054054 0.945946 7 0.985261 0.014739 8 0.922832 0.077168 9 0.922832 0.077168 10 0.985261 0.014739 11 0.985261 0.014739 12 0.985261 0.014739 13 0.985261 0.014739 14 0.922832 0.077168 15 0.054054 0.945946 16 0.985261 0.014739 17 0.286006 0.713994 18 0.985261 0.014739 19 0.922832 0.077168
# 绘制ROC曲线
# 计算假正率(fpr)和真正率(tpr),并获取阈值(thres)
fpr, tpr, thres = roc_curve(y_test, y_pred_proba[:,1])
plt.plot(fpr, tpr)
plt.show()
# 计算ROC曲线下面积(ROC AUC)得分
roc_auc = roc_auc_score(y_test, y_pred_proba[:,1])
print("ROC AUC得分:", roc_auc)
ROC AUC得分: 0.9736722483245008
# 创建包含特征名称和特征重要性的DataFrame
feature_importance = pd.DataFrame({
'特征名称': X.columns, # 特征名称列
'特征重要性': dtc.feature_importances_ # 特征重要性列
})
# 根据特征重要性降序排列DataFrame
feature_importance = feature_importance.sort_values(by='特征重要性', ascending=False).reset_index(drop=True)
# 打印展示特征重要性DataFrame
feature_importance
| 特征名称 | 特征重要性 | |
|---|---|---|
| 0 | 满意度 | 0.598109 |
| 1 | 工龄 | 0.150866 |
| 2 | 考核得分 | 0.140074 |
| 3 | 工程数量 | 0.106387 |
| 4 | 月工时 | 0.004565 |
| 5 | 工资 | 0.000000 |
'''决策树可视化需要使用graphviz插件,下载地址:https://www.graphviz.org/download/,Windows版本下载exe文件即可。
下载graphviz插件后需要安装,安装时选择添加graphviz到系统变量,否则需要手动配置环境变量,将graphviz的bin目录如C:\Program Files (x86)\Graphviz ...\bin加到系统PATH。'''
# pip install graphviz 官网下载安装好graphviz之后,cmd界面执行这条指令之后,若能成功执行这一块代码则继续后续操作,若不能则重启jupyter,将之前的所有代码重新执行一遍
from sklearn.tree import export_graphviz
import graphviz
# 指定支持中文的字体
font = "SimHei"
# 生成决策树可视化数据
dot_data = export_graphviz(dtc, out_file=None, feature_names=X.columns, filled=True,
rounded=True, special_characters=True, fontname=font)
# 生成决策树图形
graph = graphviz.Source(dot_data)
# 保存决策树图形
graph.render("result")
'result.pdf'
#from IPython.display import IFrame, display 此方法能显示,但当保存为html格式时,pdf会丢失
# 用IFrame显示result.pdf文件
#pdf_path = 'result.pdf' # PDF文件路径
#display(IFrame(pdf_path, width=800, height=500))
# 从 PIL 库中导入 Image 模块
from PIL import Image
# 打开图像文件
img0 = Image.open('result.png') # 为了显示在html上,此处自己将生成的result.pdf截图保存为result.png,然后再显示
img0
# 对根节点中的值进行解释
root_node_value = dtc.tree_.value[0]
print("根节点中的值:", root_node_value)
根节点中的值: [[9120. 2880.]]
# 从 PIL 库中导入 Image 模块
from PIL import Image
# 打开图像文件
img1 = Image.open('不纯度降低量.png')
img1
img2 = Image.open('工龄_重要性.png')
img2
# 导入所需的库
from sklearn.model_selection import cross_val_score, GridSearchCV
from sklearn.tree import DecisionTreeClassifier
# 创建决策树分类器对象
dtc = DecisionTreeClassifier()
# 设置需要调优的参数
parameters = {'max_depth': [3, 5, 7, 9, 11]}
# 使用网格搜索和交叉验证进行参数调优
gs = GridSearchCV(dtc, parameters, cv=5, scoring='roc_auc')
gs.fit(X, y)
# 获取最佳参数和最佳模型
best_dtc = gs.best_estimator_
best_params = gs.best_params_
print('最佳模型:',best_dtc)
print('最佳参数:', best_params)
最佳模型: DecisionTreeClassifier(max_depth=7)
最佳参数: {'max_depth': 7}
# 使用交叉验证评估调参前后模型的性能
acc_before = cross_val_score(dtc, X, y, scoring='roc_auc', cv=5)
acc_after = cross_val_score(best_dtc, X, y, scoring='roc_auc', cv=5)
# 打印调参前后模型的性能变化
import numpy as np
print('Accuracy before tuning:', np.mean(acc_before))
print('Accuracy after tuning:', np.mean(acc_after))
Accuracy before tuning: 0.9745519722063183 Accuracy after tuning: 0.9810684907015043
在这里,我们可以观察到通过参数调优后,模型的性能得到了显著的改善。调参前模型的准确率为0.9752,而调参后模型的准确率提高到了0.9810,这意味着模型的预测能力得到了明显的提升。这种性能的提高可以帮助模型更好地适应数据,并提高对未知数据的预测准确性。因此,通过参数调优,我们成功地改善了模型的性能,使其更适合用于实际的预测任务。
# 导入所需的库
from sklearn.model_selection import cross_val_score, GridSearchCV
from sklearn.tree import DecisionTreeClassifier
# 创建决策树分类器对象
dtc = DecisionTreeClassifier()
# 设置需要调优的参数
parameters = {
'max_depth': [5, 7, 9, 11, 13],
'criterion': ['gini', 'entropy'],
'min_samples_split': [5, 7, 9, 11, 13, 15]
}
# 使用网格搜索和交叉验证进行多参数调优
gs = GridSearchCV(dtc, parameters, cv=5, scoring='roc_auc')
gs.fit(X, y)
# 获取最佳参数和最佳模型
print('最佳模型:',best_dtc)
print('最佳参数:', best_params)
最佳模型: DecisionTreeClassifier(max_depth=7)
最佳参数: {'max_depth': 7}
# 使用交叉验证评估调参前后模型的性能
acc_before = cross_val_score(dtc, X, y, scoring='roc_auc', cv=5)
acc_after = cross_val_score(best_dtc, X, y, scoring='roc_auc', cv=5)
# 打印调参前后模型的性能变化
print('Accuracy before tuning:', np.mean(acc_before))
print('Accuracy after tuning:', np.mean(acc_after))
Accuracy before tuning: 0.974577641252129 Accuracy after tuning: 0.9807955468783056
这种性能的提升是显著的,表明通过参数调优,模型的预测能力得到了提升。这将使模型更适合用于实际的预测任务,并提高对未知数据的预测准确性。因此,经过参数调优后,模型的性能得到了显著的改善,这对于提高模型的实用性和预测能力具有重要意义。
# 导入所需的库
from sklearn.ensemble import RandomForestClassifier
import matplotlib.pyplot as plt
# 创建随机森林分类器对象
rfc = RandomForestClassifier()
# 设置需要调优的参数
parameters = {
'n_estimators': [50, 100, 150],
'max_depth': [5, 7, 9],
'min_samples_split': [2, 4, 6]
}
# 使用网格搜索和交叉验证进行多参数调优
gs = GridSearchCV(rfc, parameters, cv=5, scoring='roc_auc')
gs.fit(X, y)
# 获取最佳参数和最佳模型
best_rfc = gs.best_estimator_
best_params = gs.best_params_
print('Best parameters:', best_params)
Best parameters: {'max_depth': 9, 'min_samples_split': 4, 'n_estimators': 100}
# 训练最佳模型
best_rfc.fit(X, y)
# 可视化特征重要性
# 创建包含特征名称和特征重要性的DataFrame
feature_importance = pd.DataFrame({
'特征名称': X.columns, # 特征名称列
'特征重要性': best_rfc.feature_importances_ # 特征重要性列
})
# 根据特征重要性降序排列DataFrame
feature_importance = feature_importance.sort_values(by='特征重要性', ascending=False).reset_index(drop=True)
# 打印展示特征重要性DataFrame
feature_importance
| 特征名称 | 特征重要性 | |
|---|---|---|
| 0 | 满意度 | 0.349931 |
| 1 | 工龄 | 0.194673 |
| 2 | 工程数量 | 0.191984 |
| 3 | 月工时 | 0.144550 |
| 4 | 考核得分 | 0.114786 |
| 5 | 工资 | 0.004076 |
# 使用交叉验证评估两个模型的性能
acc_dtc = cross_val_score(best_dtc, X, y, scoring='roc_auc', cv=5)
acc_rfc = cross_val_score(best_rfc, X, y, scoring='roc_auc', cv=5)
# 打印两个模型的性能
print('决策树模型的精确度:', np.mean(acc_dtc))
print('随机森林模型的精确度:', np.mean(acc_rfc))
决策树模型的精确度: 0.9812200648919853 随机森林模型的精确度: 0.9919869445773528
面对此数据集,通过调参分得到的两个最佳模型,其中随机森林模型的性能更好。在随机森林模型中,特征"工资"参与了模型的构建和预测,并且其特征重要性为0.003946。相比之下,在决策树模型中,特征"工资"的特征重要性为0。因此,可以得出随机森林模型更加合理,能够预测得更加精准。